package com.yunhe.inspect.service.impl;

import com.yunhe.common.constant.InSpectConsts;
import com.yunhe.common.exception.ArgumentErrorException;
import com.yunhe.common.filter.ServerContextHolder;
import com.yunhe.common.model.ResultObject;
import com.yunhe.common.model.authority.Organization;
import com.yunhe.common.util.CollectionUtil;
import com.yunhe.common.util.DateTimeUtils;
import com.yunhe.common.util.StringUtil;
import com.yunhe.inspect.client.AuthorityClient;
import com.yunhe.inspect.domain.CompletionOfInspection;
import com.yunhe.inspect.domain.OrgInspectAnalysis;
import com.yunhe.inspect.domain.OrgPeopleInspectAnalysis;
import com.yunhe.inspect.domain.ProportionOfFormsByDepartment;
import com.yunhe.inspect.repository.DataInspectOrderRepository;
import com.yunhe.inspect.service.DataInspectOrderService;
import com.yunhe.inspect.service.InspectAnalysisService;
import com.yunhe.inspect.util.MyHeaderUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author zhengbo
 * @date 2021/11/17 15:10
 */
@Service
public class InspectAnalysisServiceImpl implements InspectAnalysisService {

    @Autowired
    private AuthorityClient authorityClient;

    @Autowired
    private DataInspectOrderRepository dataInspectOrderRepository;

    @Autowired
    private MyHeaderUtil myHeaderUtil;


    @Override
    public List<OrgInspectAnalysis> getOrgInspectAnalysisList() throws ArgumentErrorException {
        Long headerUser = myHeaderUtil.getHeaderUser();
        if (headerUser == null) {
            throw new ArgumentErrorException("用户登录信息已过期，请重新登录！");
        }
        String stationId = ServerContextHolder.getContext().getProjectCode();
        List<OrgInspectAnalysis> list = new ArrayList<>();
        if (stationId != null) {
            //根据虚拟园区Id查询组织列表
            //查询当前登录人的部门以及负责部门和子部门
            ResponseEntity<ResultObject<List<Organization>>> responseEntity = authorityClient.getSubOrgByLoginUser(Long.valueOf(stationId), headerUser, true);
            if (responseEntity.getBody() != null) {
                List<Organization> organizationList = responseEntity.getBody().getResults();
                if (CollectionUtil.isNotEmpty(organizationList)) {
                    List<Long> orgIds = organizationList.stream().map(Organization::getId).collect(Collectors.toList());
                    //查询完成的巡检单>0的组织
                    List<Long> orgIdList = dataInspectOrderRepository.getOrgForGreaterThanTenInspectionForm();
                    if (CollectionUtils.isNotEmpty(orgIdList)) {
                        //判断组织是否为该虚拟园区中的组织
                        orgIds.forEach(orgId -> {
                            if (orgIdList.contains(orgId)) {
                                OrgInspectAnalysis orgInspectAnalysis = new OrgInspectAnalysis();
                                orgInspectAnalysis.setOrgId(orgId);
                                list.add(orgInspectAnalysis);
                            }
                        });
                    }
                }
            }
        }
        return list;
    }

    @Override
    public List<OrgPeopleInspectAnalysis> countNumberOfInspectionOrders(Long orgId, String timeType) {
        String startTime = "";
        String endTime = "";
        Map<String, Object> map = new HashMap<>(4);
        map.put("orgId", orgId);
        if (!StringUtil.isEmpty(timeType)) {
            switch (timeType) {
                //本日
                case "day":
                    startTime = DateTimeUtils.getCurDate("yyyy-MM-dd") + " 00:00:00";
                    endTime = DateTimeUtils.getCurDate("yyyy-MM-dd") + " 23:59:59";
                    break;
                //本周
                case "week":
                    startTime = DateTimeUtils.getThisWeekOfFirstDate() + " 00:00:00";
                    endTime = DateTimeUtils.getThisWeekOfLatDate() + " 23:59:59";
                    break;
                //本月
                case "month":
                    startTime = DateTimeUtils.getCurrentMonthFirstDay() + " 00:00:00";
                    endTime = DateTimeUtils.getCurrentMonthLastDay() + " 23:59:59";
                    break;
                //本季度
                case "quarterly":
                    startTime = DateTimeUtils.dateToStrLong(DateTimeUtils.getCurrentQuarterStartTime());
                    endTime = DateTimeUtils.dateToStrLong(DateTimeUtils.getCurrentQuarterEndTime());
                    break;
                //本年
                case "year":
                    startTime = DateTimeUtils.getCurrYearFirst() + " 00:00:00";
                    endTime = DateTimeUtils.getCurrYearLast() + " 23:59:59";
                    break;
                default:
                    startTime = "";
                    endTime = "";
                    break;
            }
        }
        map.put("startTime", startTime);
        map.put("endTime", endTime);
        List<OrgPeopleInspectAnalysis> orgPeopleInspectAnalysisList = dataInspectOrderRepository.countNumberOfInspectionOrders(map);
        return orgPeopleInspectAnalysisList;
    }

    @Override
    public List<ProportionOfFormsByDepartment> countNumberOfInspectionOrdersForEachDepartment(String startTime, String endTime) throws ArgumentErrorException {
        Long headerUser = myHeaderUtil.getHeaderUser();
        if (headerUser == null) {
            throw new ArgumentErrorException("用户登录信息已过期，请重新登录！");
        }
        Map<String, Object> map = new HashMap<>(4);
        map.put("startTime", StringUtil.isEmpty(startTime) ? "" : startTime);
        map.put("endTime", StringUtil.isEmpty(endTime) ? "" : endTime);
        String stationId = ServerContextHolder.getContext().getProjectCode();
        if (stationId != null) {
            List<ProportionOfFormsByDepartment> proportionOfFormsByDepartmentList = new ArrayList<>();
            //根据角色查询组织列表
            ResponseEntity<ResultObject<List<Organization>>> responseEntity = authorityClient.getSubOrgByLoginUser(Long.valueOf(stationId), headerUser, true);
            if (responseEntity.getBody() != null) {
                List<Organization> organizationList = responseEntity.getBody().getResults();
                organizationList.forEach(organization -> {
                    map.put("orgId", organization.getId());
                    ProportionOfFormsByDepartment proportionOfFormsByDepartment = dataInspectOrderRepository.countNumberOfInspectionOrdersForEachDepartment(map);
                    if (proportionOfFormsByDepartment.getOrgId() != null) {
                        proportionOfFormsByDepartmentList.add(proportionOfFormsByDepartment);
                    }
                });

                if (CollectionUtils.isNotEmpty(proportionOfFormsByDepartmentList)) {
                    long allOrders = proportionOfFormsByDepartmentList.stream().mapToLong(ProportionOfFormsByDepartment::getDepartmentOrderQuantity).sum();
                    //小于等于三条数据时全统计
                    if (proportionOfFormsByDepartmentList.size() <= 3) {
                        proportionOfFormsByDepartmentList.forEach(proportionOfFormsByDepartment -> {
                            double percentage = new BigDecimal((double) proportionOfFormsByDepartment.getDepartmentOrderQuantity() / allOrders * 100).setScale(1, BigDecimal.ROUND_HALF_UP).doubleValue();
                            proportionOfFormsByDepartment.setDepartmentProportion(percentage);
                        });

                        return proportionOfFormsByDepartmentList;
                    } else {
                        List<ProportionOfFormsByDepartment> newProportionOfFormsByDepartmentList = new ArrayList<>();

                        //取前三高的部门展示，其他都是其他
                        proportionOfFormsByDepartmentList.sort((o1, o2) -> Long.compare(0, o1.getDepartmentOrderQuantity().compareTo(o2.getDepartmentOrderQuantity())));
                        ProportionOfFormsByDepartment top = proportionOfFormsByDepartmentList.get(0);
                        double topDouble = new BigDecimal((double) top.getDepartmentOrderQuantity() / allOrders * 100).setScale(1, BigDecimal.ROUND_HALF_UP).doubleValue();
                        top.setDepartmentProportion(topDouble);

                        ProportionOfFormsByDepartment second = proportionOfFormsByDepartmentList.get(1);
                        double secondDouble = new BigDecimal((double) second.getDepartmentOrderQuantity() / allOrders * 100).setScale(1, BigDecimal.ROUND_HALF_UP).doubleValue();
                        second.setDepartmentProportion(secondDouble);

                        ProportionOfFormsByDepartment third = proportionOfFormsByDepartmentList.get(2);
                        double thirdDouble = new BigDecimal((double) third.getDepartmentOrderQuantity() / allOrders * 100).setScale(1, BigDecimal.ROUND_HALF_UP).doubleValue();
                        third.setDepartmentProportion(thirdDouble);

                        ProportionOfFormsByDepartment other = new ProportionOfFormsByDepartment();
                        other.setDepartmentOrderQuantity(allOrders - top.getDepartmentOrderQuantity() - second.getDepartmentOrderQuantity() - third.getDepartmentOrderQuantity());
                        other.setDepartmentProportion(100.0d - topDouble - secondDouble - thirdDouble);
                        other.setOrgName("其他");
                        new ArrayList<>();
                        newProportionOfFormsByDepartmentList.add(top);
                        newProportionOfFormsByDepartmentList.add(second);
                        newProportionOfFormsByDepartmentList.add(third);
                        newProportionOfFormsByDepartmentList.add(other);

                        return newProportionOfFormsByDepartmentList;
                    }
                }
            }
        }
        return new ArrayList<>();
    }

    @Override
    public CompletionOfInspection percentageOfCompletedInspectionOrders(String startTime, String endTime) throws ArgumentErrorException {
        Long headerUser = myHeaderUtil.getHeaderUser();
        if (headerUser == null) {
            throw new ArgumentErrorException("用户登录信息已过期，请重新登录！");
        }
        CompletionOfInspection completionOfInspection = new CompletionOfInspection();
        Map<String, Object> map = new HashMap<>(8);
        startTime = StringUtil.isEmpty(startTime) ? "" : startTime;
        endTime = StringUtil.isEmpty(endTime) ? "" : endTime;
        String stationId = ServerContextHolder.getContext().getProjectCode();
        if (stationId != null) {

            Long totalOrderQuantity = 0L;
            Long totalCompletion = 0L;
            Long missingAmount = 0L;

            //根据虚拟园区Id查询组织列表
            ResponseEntity<ResultObject<List<Organization>>> responseEntity = authorityClient.getSubOrgByLoginUser(Long.valueOf(stationId), headerUser, true);
            if (responseEntity.getBody() != null) {
                List<Organization> organizationList = responseEntity.getBody().getResults();
                if (CollectionUtils.isNotEmpty(organizationList)) {
                    for (Organization organization : organizationList) {
                        map.put("startTime", startTime);
                        map.put("endTime", endTime);
                        //获取当前组织所有的工单
                        map.put("orgId", organization.getId());
                        Long totalOrderQuantityForOrg = dataInspectOrderRepository.countNumberOfInspectionOrdersForOrgId(map);
                        totalOrderQuantity = totalOrderQuantity + totalOrderQuantityForOrg;

                        //获取当前组织已完成的工单
                        map.put("inspectStatus", InSpectConsts.Inspect_Status.Finish.value());
                        Long totalCompletionForOrg = dataInspectOrderRepository.countNumberOfInspectionOrdersForOrgId(map);
                        totalCompletion = totalCompletion + totalCompletionForOrg;

                        //获取当前组织漏检的工单
                        map.remove("inspectStatus");
                        map.put("formStatus", InSpectConsts.FormStatus.Beoverdue.value());
                        Long missingAmountForOrg = dataInspectOrderRepository.countNumberOfInspectionOrdersForOrgId(map);
                        missingAmount = missingAmount + missingAmountForOrg;

                        map.clear();
                    }
                    if (totalOrderQuantity != 0) {
                        Double percentageOfInspectionCompleted = new BigDecimal((double) totalCompletion / totalOrderQuantity).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
                        completionOfInspection.setPercentageOfInspectionCompleted(percentageOfInspectionCompleted);
                    }
                    completionOfInspection.setTotalOrderQuantity(totalOrderQuantity);
                    completionOfInspection.setTotalCompletion(totalCompletion);
                    completionOfInspection.setMissingAmount(missingAmount);

                }
            }
        }
        return completionOfInspection;
    }
}
